﻿//-----------------------------------------------------------------------
// <copyright file="Host.cs" company="DylanBox">
// Copyright (c) DylanBox Corporation. All rights reserved.
// </copyright>
// <summary>Test serialize and deserialize, additional for generic class</summary>
// <reference>
//    http://msdn.microsoft.com/en-us/library/ms379564(VS.80).aspx
// </reference>
// <author>Dylan</author>
//-----------------------------------------------------------------------

using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using GenericBinaryFormatter = SerializeDeserialize.GenericFormatter<System.Runtime.Serialization.Formatters.Binary.BinaryFormatter>;
using GenericSoapFormatter = SerializeDeserialize.GenericFormatter<System.Runtime.Serialization.Formatters.Soap.SoapFormatter>;

namespace SerializeDeserialize
{ 
    class Program
    {
        static void Main(string[] args)
        {
            #region  Example 1: Serialize and Deserialize "Persons"
            // 1. Prepare an instance of "Persons"
            List<Account> dylansAccount = new List<Account>();
            dylansAccount.Add(new Account("ACBC", 123));
            dylansAccount.Add(new Account("SBCB", 456));
            Person dylan = new Person("dylan", "wang", null, 28, dylansAccount);

            List<Account> sallysAccount = new List<Account>();
            sallysAccount.Add(new Account("WJBC", 112));
            sallysAccount.Add(new Account("NBCB", 990));
            Person sally = new Person("sally", "pan", "woman", 27, sallysAccount);

            List<Person> members = new List<Person>();
            members.Add(dylan);
            members.Add(sally);
            Persons myFamily = new Persons(members);

            // 2. Begin to serialize and deserialize
            // Method 1, use System.Xml.Serialization
            // Notice: 
            //   with this method, the type Persons, Person, Account needn't to be marked with attribute [Serializable]          
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Persons));
            FileStream fs = new FileStream("myFamily.xml", FileMode.OpenOrCreate);

            using (fs)
            {
                // Serialize
                xmlSerializer.Serialize(fs, myFamily);
           
                // Deserialize
                //StreamReader sr = new StreamReader(fs, Encoding.Default);
                //StringReader stringReader = new StringReader(sr.ReadToEnd());
                //object d = (Persons)xmlSerializer.Deserialize(stringReader);
            }

            // Method 2, use System.Runtime.Serialization.IFormatter
            // with this method, type Persons, Person, Account must be marked with [Serializable]
            System.Runtime.Serialization.IFormatter formatter2 = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            Stream stream2 = new FileStream("obj.bin", FileMode.Create, FileAccess.ReadWrite);
            using (stream2)
            {
                formatter2.Serialize(stream2, myFamily);
                stream2.Seek(0, SeekOrigin.Begin);

                Persons d = (Persons)formatter2.Deserialize(stream2);
            }
            #endregion

            #region Example 2: Serialize and Deserialize object "MyGenericClass<int>"
            MyGenericClass<int> obj1 = new MyGenericClass<int>();
            IFormatter formatter = new BinaryFormatter();
            Stream stream = new FileStream("obj.bin", FileMode.Create, FileAccess.ReadWrite);
            using (stream)
            {
                formatter.Serialize(stream, obj1);
                stream.Seek(0, SeekOrigin.Begin);

                MyGenericClass<int> obj2;
                obj2 = (MyGenericClass<int>)formatter.Deserialize(stream);
            }

            // update! use a generic version of IFormatter 
            MyGenericClass<int> obj = new MyGenericClass<int>();
            IGenericFormatter format = new GenericBinaryFormatter();
            Stream stream3 = new FileStream("obj.bin", FileMode.Create, FileAccess.ReadWrite);
            using (stream3)
            {
                format.Serialize(stream3, obj); // parameter inference of "format.Serialize<MyGenericClass<int>>(stream3, obj)"
                stream3.Seek(0, SeekOrigin.Begin);
                MyGenericClass<int> obj2;
                obj2 = format.Deserialize<MyGenericClass<int>>(stream3);
            }

            #endregion
        }
    }
}
